package com.mapforge.map.tilewriter;

import java.awt.Graphics2D;
import java.util.List;

import com.mapforge.map.Tile;
import com.mapforge.map.TileLayer;
import com.mapforge.map.Tileset;
import com.mapforge.map.tools.MapToolInterface;
import com.mapforge.selection.Selection;
import com.mapforge.selection.TileSelection;

/**
 * The {@link TileWriter} interface exists to relate classes determining which
 * {@link Tile tiles} are written to a {@link TileLayer} given an input
 * {@link Selection} of tiles from a {@link Tileset}, and the destination
 * {@link Selection} from a {@link TileLayer TileLayer.}
 * 
 * @see MapToolInterface
 * @see Selection
 * @see Tileset
 * @see TileLayer
 * @author Will Morrison
 * 
 */
public interface TileWriter {
	/**
	 * Sets the {@link Tileset} this {@link TileWriter} uses for input.
	 * 
	 * @see #getTileset()
	 * @param tileset
	 *            new Tileset considered as input
	 */
	public void setTileset(Tileset tileset);

	/**
	 * Returns the {@link Tileset} used for input in this {@link TileWriter}.
	 * 
	 * @see #setTileset(Tileset)
	 * @return tileset used for input in this tile writer
	 */
	public Tileset getTileset();

	/**
	 * Sets the {@link TileLayer} destination this {@link TileWriter} writes
	 * tiles to.
	 * 
	 * @see #getTileLayer()
	 * @param layer
	 *            new TileLayer this TileWriter will write to.
	 */
	public void setTileLayer(TileLayer layer);

	/**
	 * Returns the {@link TileLayer} input this {@link TileWriter} writes
	 * {@link Tile} to.
	 * 
	 * @see #setTileLayer(TileLayer)
	 * @return TileLayer this TileWriter writes to.
	 */
	public TileLayer getTileLayer();

	public void beginPreview();

	/**
	 * This method calculates the tiles which would be written to this
	 * {@link TileWriter TileWriter's} known {@link TileLayer} given a specified
	 * tile input {@link Selection} and destination {@link Selection}, and
	 * renders these tiles with the supplied {@link Graphics2D} context.
	 * 
	 * @see #writeTiles(TileSelection, Selection)
	 * @param g
	 *            supplied graphics context
	 * @param tileSelection
	 *            selection of tiles to render to destination
	 * @param destination
	 *            destination to render tile selection to
	 */
	public void previewWrite(Graphics2D g, TileSelection tileSelection,
			Selection destination);

	public void endPreview();

	public void beginWrite();

	/**
	 * This method writes {@link Tile} given an input {@link Selection} and a
	 * destination {@link Selection}. It should return a set of points holding
	 * the the old values it has overwritten for undo support.
	 * 
	 * How the writer performs this edit should be determined by its internal
	 * state.
	 * 
	 * @see #previewWrite(Graphics2D, TileSelection, Selection)
	 * @param tileSelection
	 *            input Selection of tiles from this TileWriter's known Tileset
	 * @param destination
	 *            Selection from TileLayer this TileWriter is writing to
	 */
	public List<Tile> writeTiles(TileSelection tileSelection, Selection destination);

	public void endWrite();
}